<template>
  <van-popup v-model="isChatOpen" class="chat-modal-overlay" @click.self="closeChat">
    <div class="chat-modal">
      <beautiful-chat
        title="智能通话助理"
        placeholder="请输入消息..."
        :participants="participants"
        :titleImageUrl="titleImageUrl"
        :onMessageWasSent="onMessageWasSent"
        :messageList="messageList"
        :newMessagesCount="newMessagesCount"
        :isOpen="true"
        :open="openChat"
        :close="closeChat"
        :showEmoji="false"
        :showFile="false"
        :showEdition="true"
        :showDeletion="true"
        :showTypingIndicator="typingUser"
        :showLauncher="false"
        :showCloseButton="true"
        :colors="colors"
        :alwaysScrollToBottom="true"
        :messageStyling="true"
        @onType="handleOnType"
        @edit="editMessage"
      >
        <!-- 自定义文本消息渲染：Markdown -> HTML -->
        <template v-slot:text-message-body="{ message }">
          <div class="markdown-body" v-html="renderMd(message.data.text)"></div>
        </template>
      </beautiful-chat>
    </div>
  </van-popup>
</template>

<script>

import MarkdownIt from "markdown-it"
import DOMPurify from "dompurify"
import hljs from "highlight.js";
import "highlight.js/styles/github.css";
import { generateUUID } from '../../utils/util'
import homeApi from '../../api/homeApi'
import aiccCallApi from '../../apiaicc/aiccCallApi' // 可以换成其他主题

const md = new MarkdownIt({
  html: false,
  linkify: true,
  typographer: true,
  highlight: function (str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return `<pre class="hljs"><code>` +
          hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
          `</code></pre>`;
      } catch (__) {}
    }
    return `<pre class="hljs"><code>` + md.utils.escapeHtml(str) + `</code></pre>`;
  }
})


const base_url = process.env.BASE_API;
export default {
  name: 'vue-chat',
  components: {

  },
  props: {
    param: {
      type: Object,
      default: () => ({})
    }
  },
  computed: {
  },
  data() {
    return {
      isChatOpen: true,
      newMessagesCount: 0,
      typingUser: '',
      titleImageUrl: '',
      participants: [
        // {
        //   id: 'ai',
        //   name: '智能通话助理',
        //   imageUrl: ''
        // }
      ],
      messageList: [
        {
          author: 'ai',
          type: 'text',
          data: { text: '正在总结本次通话，请稍等...' }
        }
      ],
      colors: {
        header: { bg: '#4e8cff', text: '#ffffff' },
        launcher: { bg: '#4e8cff' },
        sentMessage: { bg: '#4e8cff', text: '#ffffff' },
        receivedMessage: { bg: '#eaeaea', text: '#222222' },
        userInput: { bg: '#f4f7f9', text: '#565867' },
        messageList: { bg: '#ffffff' }
      },
      _scrollTimeout: null,
      eventSource: null,
      chatId: '',
      asrList: [],
      isSendAsr: false,
      conversationId: '',
      billId: '',
      billType: '',
    }
  },
  mounted() {

    this.isSendAsr = false
    this.chatId = ''
    this.conversationId = ''

    this.billId = this.param.billId
    this.billType = this.param.billType
    if (this.billId && this.billType) {
      this.getCallAsr()
    } else {
      this.openChat()
    }
  },
  // 页面离开前触发
  methods: {
    onMessageWasSent(message) {
      let that = this
      this.messageList.push(message)
      this.newMessagesCount = 0

      this.messageList.push({
        author: 'ai',
        type: 'text',
        data: { text: `思考中` }
      })

      let param={
        chatId: this.chatId,
        chatContent: message.data.text,
        conversationId: this.conversationId
      }
      homeApi.askQuestion(param)

      this.getMessage()

    },
    openChat() {
      // this.isChatOpen = true
      this.newMessagesCount = 0

      const uuid = generateUUID();
      this.chatId = uuid
      let that = this

      if (window.EventSource) {
        that.eventSource = new EventSource(`${base_url}/stream-sse/createSse?uid=${uuid}`)
        that.eventSource.onopen = function(event) {
          console.log('SSE通话助理连接成功' + new Date().Format('yyyy-MM-dd hh:mm:ss'))
          that.initAsr()
        }
        that.eventSource.onerror = (e) => {
          console.log('SSE通话助理连接失败' + new Date().Format('yyyy-MM-dd hh:mm:ss'))
        }
      } else {
        console.log('不支持sse')
      }
    },
    closeChat() {
      homeApi.closeSse(this.chatId)
      if (this.eventSource) {
        homeApi.closeSse(this.chatId)
        this.eventSource.close()
        this.eventSource = null
      }
      this.chatId = ''
      this.conversationId = ''
      this.$emit('close')
      this.$emit('input', false) // v-model
    },
    handleOnType(user) {
      this.typingUser = ''
    },
    editMessage(message) {
      alert('编辑消息: ' + JSON.stringify(message))
    },
    renderMd(text) {
      const html = md.render(text || '')
      return DOMPurify.sanitize(html)
    },
    scrollToBottom() {
      this.$nextTick(() => {
        const list = this.$el.querySelector('.sc-message-list');
        if (list) list.scrollTop = list.scrollHeight;
      });
    },

    async getCallAsr() {
      const res = await aiccCallApi.getCallAsr({
        id: this.billId,
        type: this.billType
      })
      console.log(res.data);
      this.asrList = res.data.asr
      this.openChat()   // 这里保证在请求完成后执行
    },
    initAsr() {
      if (!this.isSendAsr) {
        let param={
          chatId: this.chatId,
          chatContent: this.asrList
        }
        homeApi.askQuestion(param)
        this.getMessage(true)
        this.isSendAsr = true
      }
    },
    getMessage(isNew = false) {

      const lastIndex = this.messageList.length - 1
      let that = this
      that.eventSource.onmessage = function(event) {
        console.log(event.data)
        if (that.messageList[lastIndex].data.text == '思考中') that.messageList[lastIndex].data.text = ''
        if (that.messageList[lastIndex].data.text == '正在总结本次通话，请稍等...') that.messageList[lastIndex].data.text = ''
        const dataStr = event.data.slice(5).trim()
        if (dataStr === '[DONE]') return
        try {
          const obj = JSON.parse(dataStr)
          var delta = null
          if (that.conversationId === '' && obj && obj.conversation_id) {
            that.conversationId = obj.conversation_id
          }
          if (obj && obj.choices && obj.choices[0] && obj.choices[0].delta && obj.choices[0].delta.content && obj.choices[0].delta.content.msg) {
            delta = obj.choices[0].delta.content.msg
          }

          if (delta) that.messageList[lastIndex].data.text += delta
        } catch (e) {
          console.error('dataStr 解析失败', dataStr)
          console.error('JSON 解析失败', e)
          that.messageList[lastIndex].data.text = '发生错误，请重试！'
        }
        if (!that._scrollTimeout) {
          that._scrollTimeout = setTimeout(() => {
            that.scrollToBottom()
            that._scrollTimeout = null
          }, 50)
        }
      }
    }

  }
}
</script>

<style>

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, sub, sup, tt, var,
b, u, i, center, dl, dt, dd, ol, ul, li,
fieldset, form, label, legend, table, caption,
tbody, tfoot, thead, tr, th, td, article,
aside, canvas, details, embed, figure,
figcaption, footer, header, menu, nav,
output, ruby, section, summary, time, mark,
audio, video, input {
  font-weight: normal;
}
strong {
  font-weight: bold;
}

ol li {
  list-style-type: decimal; /* 显示数字 */
  margin-left: 16px;        /* 缩进，避免数字贴边 */
}

ul li {
  list-style-type: disc;    /* 显示圆点 */
  margin-left: 16px;
}

.chat-modal-overlay {
  position: fixed;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0.4);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.chat-header {
  background-color: #4e8cff;
  color: #fff;
  padding: 10px 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: bold;
}

.close-btn {
  background: transparent;
  border: none;
  font-size: 20px;
  color: #fff;
  cursor: pointer;
}

.beautiful-chat {
  flex: 1;
  overflow: hidden;
}



.sc-message--avatar {
  display: none;
}

.sc-message--text {
  font-weight: unset;
  font-size: 14px;
}

.sc-message--text .markdown-body {
  font-size: 14px;
  line-height: 1.6;
}

.sc-message--text .markdown-body pre {
  background: #f6f8fa;
  padding: 8px;
  border-radius: 6px;
  overflow-x: auto;
}

.sc-message--text .markdown-body code {
  background: #f2f2f2;
  padding: 2px 4px;
  border-radius: 4px;
}
.sc-message--text .markdown-body{
  word-break: break-word; /* 避免长单词撑破布局 */
  line-height: 1.6;
}

.sc-message--text .markdown-body pre {
  border-radius: 8px;
  overflow-x: hidden;        /* 不显示横向滚动 */
  white-space: pre-wrap;      /* 自动换行 */
  word-break: break-word;     /* 防止长单词撑破布局 */
}

.sc-message--text .markdown-body pre code {
  font-family: monospace;
  font-size: 14px;
  line-height: 1.5;
  display: block;
}

@media (max-width: 450px) {
  .sc-message {
    width: 90% !important;
  }
}

/* PC端：气泡不要太宽，保持在 60% 左右 */
@media (min-width: 1025px) {

  .chat-modal {
    width: 800px;           /* PC 端默认宽度 */
    height: 80%;            /* 高度自适应 */
    max-width: 90%;         /* 小屏幕自动缩放 */
    max-height: 90%;
    background: #fff;
    border-radius: 12px;
    display: flex;
    flex-direction: column;
    box-shadow: 0 10px 40px rgba(0,0,0,0.3);
    overflow: hidden;
  }

  .sc-message {
    width: 780px !important;
    max-width: 800px; /* 再加个最大宽度，避免超大屏时太长 */
  }
  .sc-chat-window {
    width: 800px !important;
    height: 80% !important;
    max-height: unset !important;
    right: unset !important;
    bottom: unset !important;
  }
}


</style>
